# Maintainer: Martell Malone <martellmalone@gmail.com>
# Maintainer: Alexey Pavlov <alexpux@gmail.com>
# Contributor: Ray Donnelly <mingw.android@gmail.com>

_realname=clang
pkgbase=mingw-w64-${_realname}
pkgname=("${MINGW_PACKAGE_PREFIX}-${_realname}"
         "${MINGW_PACKAGE_PREFIX}-clang-analyzer"
         "${MINGW_PACKAGE_PREFIX}-clang-tools-extra"
         "${MINGW_PACKAGE_PREFIX}-compiler-rt"
         "${MINGW_PACKAGE_PREFIX}-libc++abi"
         "${MINGW_PACKAGE_PREFIX}-libc++"
         "${MINGW_PACKAGE_PREFIX}-lld"
         "${MINGW_PACKAGE_PREFIX}-libunwind"
         "${MINGW_PACKAGE_PREFIX}-llvm"
         #"${MINGW_PACKAGE_PREFIX}-lldb"
         )
pkgver=3.9.0
pkgrel=1
pkgdesc="C language family frontend for LLVM (mingw-w64)"
arch=('any')
url="http://llvm.org"
license=("custom:University of Illinois/NCSA Open Source License")
makedepends=("${MINGW_PACKAGE_PREFIX}-cmake"
             "${MINGW_PACKAGE_PREFIX}-gcc"
             "${MINGW_PACKAGE_PREFIX}-libffi"
             "${MINGW_PACKAGE_PREFIX}-pkg-config"
             "${MINGW_PACKAGE_PREFIX}-python3-sphinx"
             "${MINGW_PACKAGE_PREFIX}-python2"
             "tar"
             "groff")
depends=("${MINGW_PACKAGE_PREFIX}-gcc")
#options=('debug' '!strip')
source=(http://llvm.org/releases/${pkgver}/llvm-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/cfe-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/compiler-rt-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/test-suite-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/libcxx-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/libcxxabi-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/clang-tools-extra-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/lld-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/lldb-${pkgver}.src.tar.xz{,.sig}
        http://llvm.org/releases/${pkgver}/libunwind-${pkgver}.src.tar.xz{,.sig}
        "0001-Fix-GetHostTriple-for-mingw-w64-in-msys.patch"
        "0002-use-DESTDIR-on-windows.patch"
        "0003-generate-proper-library-names-mingw.patch"
        "0004-killthedoctor-mingw.patch"
        "0012-Set-the-x86-arch-name-to-i686-for-mingw-w64.patch"
        "0013-mingw-w64-dont-have-dl-library.patch"
        "0014-dont-create-cl-mingw.patch"
        "0018-mingw-enable-static-libclang.patch"
        "0021-missing-include.patch"
        "0041-libcxx-add-support-for-mingw-w64.patch"
        "0061-libunwind-add-support-for-mingw-w64.patch")
# Some patch notes :)
#0001-0009 -> llvm
#0011-0019 -> clang
#0021-0029 -> rt
#0031-0039 -> lld
#0041-0049 -> c++
#0051-0059 -> lldb
#0061-0069 -> libunwind
sha256sums=('66c73179da42cee1386371641241f79ded250e117a79f571bbd69e56daa48948'
            'SKIP'
            '7596a7c7d9376d0c89e60028fe1ceb4d3e535e8ea8b89e0eb094e0dcb3183d28'
            'SKIP'
            'e0e5224fcd5740b61e416c549dd3dcda92f10c524216c1edb5e979e42078a59a'
            'SKIP'
            'fdc261b686a75351e691be36a4cbad141096998c03d1487c35b6253d8e5bf408'
            'SKIP'
            'd0b38d51365c6322f5666a2a8105785f2e114430858de4c25a86b49f227f5b06'
            'SKIP'
            'b037a92717856882e05df57221e087d7d595a2ae9f170f7bc1a23ec7a92c8019'
            'SKIP'
            '5b7aec46ec8e999ec683c87ad744082e1133781ee4b01905b4bdae5d20785f14'
            'SKIP'
            '986e8150ec5f457469a20666628bf634a5ca992a53e157f3b69dbc35056b32d9'
            'SKIP'
            '61280e07411e3f2b4cca0067412b39c16b0a9edd19d304d3fc90249899d12384'
            'SKIP'
            '66675ddec5ba0d36689757da6008cb2596ee1a9067f4f598d89ce5a3b43f4c2b'
            'SKIP'
            '0804146b32138d55c611336cc81e1783c29a8fab0fe62f248ba1ad7acc711c4d'
            '76bcdcae0ef3a4d3ae7082b7fcd668e9560e63fb82068c3f889f9e89b9becf4a'
            '6a95ed671876a6de04799d15bf7485d628016bb4a95a6764217ad452d8eed0d8'
            'e83fe9effaa3d0ba21d3bb98bfd471dc0acd2dd99c72695fb33685d69f8e2a76'
            '13a95a61e9c1c44c18a69947734e07515332a549446394f48b86b52511d221de'
            '8f35b80eca6c18df020b176eee4eb95901c31e3e640848a6d606983aca15a3af'
            'b03cfc7ebbbfb847e88ae3569d9dcafb01f179b06f1312de29fbd5b7cf906617'
            '0e45e76ee6d6658de52edb7b508a8bcc9f10ff0b295ff2a4e35577136a40c6a5'
            'a0933775b979b4879e220358b1076d8eeb9170403d0d190b1340d179fcd3cd1e'
            '5b8edbbb638c906216e20229529e8348abc50d5886d20e07af08543e1e574e94'
            '0a5529a5e9871ec5252c3853f1fdda69253c1a7505837e9c45ae14bcb76a8660')
validpgpkeys=('B6C8F98282B944E3B0D5C2530FC3042E345AD05D') # Hans Wennborg, Google.      
noextract=(cfe-${pkgver}.src.tar.xz
           libcxx-${pkgver}.src.tar.xz
           lldb-${pkgver}.src.tar.xz
           test-suite-${pkgver}.src.tar.xz
           )

prepare() {
  plain "Extracting clang-${pkgver}.src.tar.xz due to symlink(s) without pre-existing target(s)"
  [[ -d ${srcdir}/cfe-${pkgver} ]] && rm -rf ${srcdir}/cfe-${pkgver}
  [[ -d ${srcdir}/cfe-${pkgver} ]] || tar -xJvf ${srcdir}/cfe-${pkgver}.src.tar.xz -C ${srcdir} || true

  plain "Extracting libcxx-${pkgver}.src.tar.xz due to symlink(s) without pre-existing target(s)"
  [[ -d ${srcdir}/libcxx-${pkgver} ]] && rm -rf ${srcdir}/libcxx-${pkgver}
  [[ -d ${srcdir}/libcxx-${pkgver} ]] || tar -xJvf ${srcdir}/libcxx-${pkgver}.src.tar.xz -C ${srcdir} || true

  plain "Extracting lldb-${pkgver}.src.tar.xz due to symlink(s) without pre-existing target(s)"
  [[ -d ${srcdir}/lldb-${pkgver} ]] && rm -rf ${srcdir}/lldb-${pkgver}
  [[ -d ${srcdir}/lldb-${pkgver} ]] || tar -xJvf ${srcdir}/lldb-${pkgver}.src.tar.xz -C ${srcdir} || true

  cd "${srcdir}/llvm-${pkgver}.src"
  patch -p1 -i "${srcdir}/0001-Fix-GetHostTriple-for-mingw-w64-in-msys.patch"
  patch -p1 -i "${srcdir}/0002-use-DESTDIR-on-windows.patch"
  patch -p1 -i "${srcdir}/0003-generate-proper-library-names-mingw.patch"
  patch -p1 -i "${srcdir}/0004-killthedoctor-mingw.patch"

  cd "${srcdir}/cfe-${pkgver}.src"
  patch -p1 -i "${srcdir}/0012-Set-the-x86-arch-name-to-i686-for-mingw-w64.patch"
  patch -p1 -i "${srcdir}/0013-mingw-w64-dont-have-dl-library.patch"
  patch -p1 -i "${srcdir}/0014-dont-create-cl-mingw.patch"
  patch -p1 -i "${srcdir}/0018-mingw-enable-static-libclang.patch"

  cd "${srcdir}/compiler-rt-${pkgver}.src"
  patch -p1 -i ${srcdir}/0021-missing-include.patch

  cd "${srcdir}/lld-${pkgver}.src"

  cd "${srcdir}/libcxx-${pkgver}.src"
  patch -p1 -i "${srcdir}/0041-libcxx-add-support-for-mingw-w64.patch"

  cd "${srcdir}/libunwind-${pkgver}.src"
  patch -p1 -i "${srcdir}/0061-libunwind-add-support-for-mingw-w64.patch"

  # At the present, clang must reside inside the LLVM source code tree to build
  # See http://llvm.org/bugs/show_bug.cgi?id=4840

  cd "${srcdir}"/llvm-${pkgver}.src
# note you need to ignore failure if there is stuff that already exists
  mv "${srcdir}/cfe-${pkgver}.src"               tools/clang | true
  mv "${srcdir}/clang-tools-extra-${pkgver}.src" tools/clang/tools/extra | true
  mv "${srcdir}/lld-${pkgver}.src"               tools/lld | true
  mv "${srcdir}/lldb-${pkgver}.src"              tools/lldb | true
  mv "${srcdir}/compiler-rt-${pkgver}.src"       projects/compiler-rt | true
  mv "${srcdir}/libcxxabi-${pkgver}.src"         projects/libcxxabi | true
  mv "${srcdir}/libcxx-${pkgver}.src"            projects/libcxx | true
  mv "${srcdir}/libunwind-${pkgver}.src"         projects/libunwind | true
  #mv "${srcdir}/testsuite-${pkgver}.src"         projects/test-suite | true
}

build() {
  cd "${srcdir}"

  [[ -d build-${CARCH} ]] && rm -rf build-${CARCH}
  mkdir build-${CARCH} && cd build-${CARCH}

  local -a extra_config

  if check_option "debug" "y"; then
    extra_config+=(-DCMAKE_BUILD_TYPE=Debug)
    VERBOSE="VERBOSE=1"
  else
    extra_config+=(-DCMAKE_BUILD_TYPE=Release)
  fi

  # Include location of libffi headers in CPPFLAGS
  FFI_INCLUDE_DIR="$(pkg-config --cflags libffi)"
  FFI_INCLUDE_DIR=$(echo $FFI_INCLUDE_DIR | sed 's|-I||g')

  # "Ninja" cant install each component seperately
  # https://github.com/martine/ninja/issues/932

  PATH=${MINGW_PREFIX}/bin:/usr/bin \
  MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
  ${MINGW_PREFIX}/bin/cmake.exe \
    -G"MSYS Makefiles" \
    -DCMAKE_SYSTEM_IGNORE_PATH=/usr/lib \
    -DCMAKE_MAKE_PROGRAM="/usr/bin/make.exe" \
    -DCMAKE_C_COMPILER="${MINGW_PREFIX}/bin/gcc.exe" \
    -DCMAKE_CXX_COMPILER="${MINGW_PREFIX}/bin/g++.exe" \
    -DFFI_INCLUDE_DIR="${FFI_INCLUDE_DIR}" \
    -DCMAKE_C_FLAGS="${CFLAGS}" \
    -DCMAKE_CXX_FLAGS="${CXXFLAGS} ${CPPFLAGS}" \
    -DCMAKE_INSTALL_PREFIX=${MINGW_PREFIX} \
    -DLLVM_TARGETS_TO_BUILD="ARM;X86" \
    -DLLVM_ENABLE_ASSERTIONS=OFF \
    -DLLVM_ENABLE_THREADS=1 \
    -DPYTHON_EXECUTABLE=${MINGW_PREFIX}/bin/python2.exe \
    -DLLVM_ENABLE_FFI=ON \
    -DLLVM_ENABLE_SPHINX=ON \
    -DCMAKE_CXX_FLAGS="-D_GNU_SOURCE -D_LIBCPP_HAS_NO_CONSTEXPR" \
    -DLIBCLANG_BUILD_STATIC=ON \
    -DLIBCXX_ENABLE_SHARED=OFF \
    -DLIBCXXABI_ENABLE_SHARED=OFF \
    -DLIBUNWIND_ENABLE_SHARED=OFF \
    "${extra_config[@]}" \
    ../llvm-${pkgver}.src

  make ${VERBOSE}

  # Disable automatic installation of components that go into subpackages
  # -i.orig to check what has been removed in-case it starts dropping more than it should
  #
  sed -i.orig '/\(clang\|lld\|lldb\)\/cmake_install.cmake/d' tools/cmake_install.cmake
  sed -i.orig '/\(extra\|scan-build\|scan-view\)\/cmake_install.cmake/d' tools/clang/tools/cmake_install.cmake
# sed -i.orig '/\(compiler-rt\|libcxxabi\|libcxx\)\/cmake_install.cmake/d' projects/cmake_install.cmake
  sed -i.orig '/\(compiler-rt\|libcxxabi\|libcxx\|libunwind\)\/cmake_install.cmake/d' projects/cmake_install.cmake
}

#check() {
#  cd "${srcdir}"/build-${CARCH}
#  # Remove || true once testcase doesn't cause failures.
#  make check || true
#}

package_llvm() {
  pkgdesc="Low Level Virtual Machine (mingw-w64)"
  #depends=("${MINGW_PACKAGE_PREFIX}-gcc-libs") # "compiler-rt"
  install=llvm-${CARCH}.install

  cd "${srcdir}"/llvm-${pkgver}.src

  make -C ../build-${CARCH} DESTDIR="${pkgdir}" install

  install -Dm644 LICENSE.TXT "${pkgdir}${MINGW_PREFIX}/share/licenses/llvm/LICENSE"

  # Install CMake stuff
  install -d "${pkgdir}"${MINGW_PREFIX}/share/llvm/cmake/{modules,platforms}
  install -Dm644 "${srcdir}"/llvm-${pkgver}.src/cmake/modules/*.cmake "${pkgdir}"${MINGW_PREFIX}/share/llvm/cmake/modules/
  install -Dm644 "${srcdir}"/llvm-${pkgver}.src/cmake/platforms/*.cmake "${pkgdir}"${MINGW_PREFIX}/share/llvm/cmake/platforms/

  # FileCheck is needed to build rust.
  install -Dm755 "${srcdir}"/build-${CARCH}/bin/FileCheck.exe "${pkgdir}${MINGW_PREFIX}/bin/FileCheck.exe"
}

package_compiler-rt() {
  pkgdesc="Runtime libraries for Clang and LLVM (mingw-w64)"
  url="http://compiler-rt.llvm.org/"
  depends=("${MINGW_PACKAGE_PREFIX}-llvm=${pkgver}-${pkgrel}")

  cd "${srcdir}"/llvm-${pkgver}.src
  make -C ../build-${CARCH}/projects/compiler-rt DESTDIR="${pkgdir}" install
 }

package_libcxxabi() {
  pkgdesc="C++ Standard Library Support (mingw-w64)"
  url="http://libcxxabi.llvm.org/"
  depends="${MINGW_PACKAGE_PREFIX}-libunwind" 

  cd "${srcdir}/llvm-${pkgver}.src"
  make -C ../build-${CARCH}/projects/libcxxabi -j1 DESTDIR="${pkgdir}" install
}

package_libcxx() {
  pkgdesc="C++ Standard Library (mingw-w64)"
  url="http://libcxx.llvm.org/"

  cd "${srcdir}/llvm-${pkgver}.src"
  make -C ../build-${CARCH}/projects/libcxx -j1 DESTDIR="${pkgdir}" install
}

package_libunwind() {
  pkgdesc='A new implementation of a stack unwinder for C++ exceptions (mingw-w64)'
  url='http://llvm.org'
  
  cd "${srcdir}/llvm-${pkgver}.src"
  make -C ../build-${CARCH}/projects/libunwind -j1 DESTDIR="${pkgdir}" install
}

package_lldb() {
  pkgdesc="Next generation, high-performance debugger (mingw-w64)"
  url="http://lldb.llvm.org/"
  depends=("${MINGW_PACKAGE_PREFIX}-readline"
           "${MINGW_PACKAGE_PREFIX}-libxml2"
           "${MINGW_PACKAGE_PREFIX}-python2")

  cd "${srcdir}/llvm-${pkgver}.src"

  make -C ../build-${CARCH}/tools/lldb DESTDIR="${pkgdir}" install

  # Compile Python scripts
  python2 -m compileall "${pkgdir}${MINGW_PREFIX}/lib/python2.7/site-packages/lldb"
  python2 -O -m compileall "${pkgdir}${MINGW_PREFIX}/lib/python2.7/site-packages/lldb"

  install -Dm644 tools/lldb/LICENSE.TXT "${pkgdir}${MINGW_PREFIX}/share/licenses/$pkgname/LICENSE"
}

package_lld() {
  pkgdesc="Linker tools for LLVM (mingw-w64)"
  url="http://lld.llvm.org/"

  cd "${srcdir}/llvm-${pkgver}.src"
  make -C ../build-${CARCH}/tools/lld -j1 DESTDIR="${pkgdir}" install
}

package_clang() {
  pkgdesc="C language family frontend for LLVM (mingw-w64)"
  url="http://clang.llvm.org/"
  depends=("${MINGW_PACKAGE_PREFIX}-llvm=${pkgver}-${pkgrel}")

  cd "${srcdir}/llvm-${pkgver}.src"
  make -C ../build-${CARCH}/tools/clang DESTDIR="${pkgdir}" install

  # Install static clang library ..
  cp ../build-${CARCH}/lib/libclang.a ${pkgdir}${MINGW_PREFIX}/lib/
}

package_clang-analyzer() {
  pkgdesc="A source code analysis framework (mingw-w64)"
  url="http://clang-analyzer.llvm.org/"
  depends=("${MINGW_PACKAGE_PREFIX}-clang=${pkgver}-${pkgrel}"
           "${MINGW_PACKAGE_PREFIX}-python2")

  cd "${srcdir}/llvm-${pkgver}.src"
  make -C ../build-${CARCH}/tools/clang/tools/scan-build -j1 DESTDIR="${pkgdir}" install
  make -C ../build-${CARCH}/tools/clang/tools/scan-view -j1 DESTDIR="${pkgdir}" install

  # Use Python 2
  sed -i \
    -e 's|env python$|&2|' \
    -e 's|/usr/bin/python$|&2|' \
    "${pkgdir}"${MINGW_PREFIX}/bin/scan-view

  # Compile Python scripts
  python2 -m compileall "${pkgdir}"${MINGW_PREFIX}/bin/clang-analyzer
  python2 -O -m compileall "${pkgdir}"${MINGW_PREFIX}/lib/clang-analyzer
  install -Dm644 LICENSE.TXT "${pkgdir}"${MINGW_PREFIX}/share/licenses/clang-analyzer/LICENSE
}

package_clang-tools-extra() {
  pkgdesc="Extra tools built using Clang's tooling APIs (mingw-w64)"
  url="http://clang.llvm.org/"

  cd "${srcdir}/llvm-${pkgver}.src"
  make -C ../build-${CARCH}/tools/clang/tools/extra -j1 DESTDIR="${pkgdir}" install
}

# Wrappers
package_mingw-w64-i686-clang(){
  package_clang
}

package_mingw-w64-i686-clang-analyzer(){
  package_clang-analyzer
}

package_mingw-w64-i686-clang-tools-extra(){
  package_clang-tools-extra
}

package_mingw-w64-i686-compiler-rt(){
  package_compiler-rt
}

package_mingw-w64-i686-libc++abi(){
  package_libcxxabi
}

package_mingw-w64-i686-libc++(){
  package_libcxx
}

package_mingw-w64-i686-lld(){
  package_lld
}

package_mingw-w64-i686-lldb(){
  package_lldb
}

package_mingw-w64-i686-libunwind(){
  package_libunwind
}

package_mingw-w64-i686-llvm(){
  package_llvm
}

package_mingw-w64-x86_64-clang(){
  package_clang
}

package_mingw-w64-x86_64-clang-analyzer(){
  package_clang-analyzer
}

package_mingw-w64-x86_64-clang-tools-extra(){
  package_clang-tools-extra
}

package_mingw-w64-x86_64-compiler-rt(){
  package_compiler-rt
}

package_mingw-w64-x86_64-libc++abi(){
  package_libcxxabi
}

package_mingw-w64-x86_64-libc++(){
  package_libcxx
}

package_mingw-w64-x86_64-lld(){
  package_lld
}

package_mingw-w64-x86_64-lldb(){
  package_lldb
}

package_mingw-w64-x86_64-libunwind(){
  package_libunwind
}

package_mingw-w64-x86_64-llvm(){
  package_llvm
}

# vim:set ts=2 sw=2 et:
